package at.jku.se.fastsell.gui;

import java.util.Timer;
import java.util.TimerTask;

import at.jku.se.fastsell.FastsellUI;
import at.jku.se.fastsell.data.Auction;
import at.jku.se.fastsell.data.DataAccess;
import at.jku.se.fastsell.data.User;

import com.vaadin.data.util.converter.StringToDoubleConverter;
import com.vaadin.data.validator.DoubleRangeValidator;
import com.vaadin.navigator.ViewChangeListener.ViewChangeEvent;
import com.vaadin.server.VaadinSession;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.Component;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.Notification;
import com.vaadin.ui.TextField;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.themes.Reindeer;

/**
 * Detail view for auction
 */
public class AuctionDetailView extends MainView implements IViewStatus {

	private static final long serialVersionUID = 1L;

	public static String NAME = "auctionDetail";

	private VerticalLayout mainPanel;
	private HorizontalLayout bidPanel;
	private Label lblTitle, lblDescription, lblCurPrice, lblHighestBidder, lblBidCount, lblRemainingTime, lblStartDate, lblEndDate, lblSeller;
	private TextField txtBid;
	private Button btnPlaceBid, btnBack;

	private Timer timer;
	
	private Auction loadedAuction;

	// ----------------------------------------------------------------------------------

	public AuctionDetailView() {
		this.setContent(buildMainLayout());
	}

	// ----------------------------------------------------------------------------------

	private Component buildMainLayout() {
		mainPanel = new VerticalLayout();
		mainPanel.setSpacing(true);

		lblTitle = new Label();
		lblTitle.setStyleName(Reindeer.LABEL_H1);
		mainPanel.addComponent(lblTitle);

		lblDescription = new Label();
		mainPanel.addComponent(lblDescription);

		lblCurPrice = new Label();
		mainPanel.addComponent(lblCurPrice);

		lblHighestBidder = new Label();
		mainPanel.addComponent(lblHighestBidder);
		
		lblBidCount = new Label();
		mainPanel.addComponent(lblBidCount);
		
		lblRemainingTime = new Label();
		mainPanel.addComponent(lblRemainingTime);

		lblStartDate = new Label();
		mainPanel.addComponent(lblStartDate);

		lblEndDate = new Label();
		mainPanel.addComponent(lblEndDate);

		lblSeller = new Label();
		mainPanel.addComponent(lblSeller);

		bidPanel = new HorizontalLayout();
		bidPanel.setSpacing(true);
		mainPanel.addComponent(bidPanel);

		txtBid = new TextField();
		txtBid.setImmediate(true);
		txtBid.setConverter(new StringToDoubleConverter());
		bidPanel.addComponent(txtBid);

		btnPlaceBid = new Button();
		btnPlaceBid.addClickListener(new ClickListener() {

			private static final long serialVersionUID = 1L;

//			@Override
			public void buttonClick(ClickEvent event) {
				if (loadedAuction != null) {
					try {
						if (txtBid.isValid()) {
							double bidPrice = Double.parseDouble(txtBid.getValue());
							String username = VaadinSession.getCurrent().getSession().getAttribute("user").toString();
							loadedAuction = DataAccess.placeBid(loadedAuction, bidPrice, username);
							Notification.show("Bid successfully placed");
							refreshAuctionData(loadedAuction);
						} else {
							Notification.show("Please check bid", Notification.Type.ERROR_MESSAGE);
						}
					} catch (Exception e) {
						Notification.show("Was not able to place bid, please try agin: " + e.toString(), Notification.Type.ERROR_MESSAGE);
					}
				}
			}
		});
		bidPanel.addComponent(btnPlaceBid);
		bidPanel.setComponentAlignment(btnPlaceBid, Alignment.BOTTOM_RIGHT);

		btnBack = new Button("Back");
		btnBack.addClickListener(new ClickListener() {

			private static final long serialVersionUID = 1L;

//			@Override
			public void buttonClick(ClickEvent event) {
				FastsellUI.navigateTo(AllAuctionsView.NAME);
			}
		});
		mainPanel.addComponent(btnBack);

		return mainPanel;
	}

	private void refreshAuctionData(Auction auction) {
		if (auction != null) {
			this.loadedAuction = auction;

			lblTitle.setValue("Auction details: " + auction.getTitle());
			lblDescription.setValue("Description" + auction.getDescription());
			lblCurPrice.setValue("Current Price: " + auction.getCurPrice());
			
			if (auction.hasBids()) {
				User bidder = auction.getHighestBidder();
				if (bidder.getName().equals(getUser())) {
					lblHighestBidder.setValue("Highest bidder: YOU!");
				} else {
					lblHighestBidder.setValue("Highest bidder: " + bidder.getName());
				}
			} else {
				lblHighestBidder.setValue("Highest bidder: -");
			}
			
			lblBidCount.setValue("Bids: " + auction.getBidCount());
			lblRemainingTime.setValue("Remaining time: " + auction.getRemainingTime());
			lblStartDate.setValue("Start date: " + auction.getStart());
			lblEndDate.setValue("End date: " + auction.getEnd());
			lblSeller.setValue("Seller: " + auction.getSeller().toString());
			// --
			txtBid.setCaption("Place a bid");
			txtBid.setValue(String.valueOf((auction.getCurPrice() + 1.0)));
			txtBid.removeAllValidators();
			txtBid.addValidator(new DoubleRangeValidator("Not a valid number or not greater than current price", auction.getCurPrice() + 0.1,
					10000D));
			// --
			btnPlaceBid.setCaption("Place bid");
			btnPlaceBid.setEnabled(auction.isActive());

			this.loadedAuction = auction;
		} else {
			Notification.show("Could not refresh auction data", Notification.Type.ERROR_MESSAGE);
		}
	}

	// ----------------------------------------------------------------------------------

	@Override
	public void enter(ViewChangeEvent event) {
		super.enter(event);
				
		if (event.getParameters() != null) {
			try {
				// Use auction ID to reach AuctionDetailView per link
				Long auctionID = Long.parseLong(event.getParameters().split("/")[0]);
				Auction a = DataAccess.getAuctionByID(auctionID);
				refreshAuctionData(a);
			} catch (Exception e) {
				btnPlaceBid.setEnabled(false);
				Notification.show("ERROR: " + e.toString(), Notification.Type.ERROR_MESSAGE);
			}
		}

		if (timer == null) {
			timer = new Timer();
			timer.scheduleAtFixedRate(new TimerTask() {

				@Override
				public void run() {
					refreshAuctionData(loadedAuction);
				}
			}, FastsellUI.POLL_INTERVAL, FastsellUI.POLL_INTERVAL);
		}
	}

//	@Override
	public void setInactive() {
		if (timer != null) {
			timer.cancel();
			timer = null;
		}
	}

//	@Override
	public String getName() {
		return NAME;
	}
	
}
